@********************************************************************
@*          crt0.s                                                  *
@*            Start Up Routine (for GAS)                            *
@*                                                                  *
@*          Copyright (C) 1999-2001 NINTENDO Co.,Ltd.               *
@********************************************************************
    .INCLUDE    "AgbDefine.s"
    .INCLUDE    "AgbMemoryMap.s"
    .INCLUDE    "AgbSyscallDefine.s"
    .INCLUDE    "AgbMacro.s"
    .TEXT

    .GLOBAL     _start
_start:
    .INCLUDE    "rom_header.s"

@--------------------------------------------------------------------
@-                          Reset                                   -
@--------------------------------------------------------------------
    .EXTERN     AgbMain
    .GLOBAL     start_vector
    .CODE 32
start_vector:
        mov     r0, #PSR_IRQ_MODE       @ Switch to IRQ Mode
        msr     cpsr, r0
        ldr     sp, sp_irq              @ Set SP_irq
        mov     r0, #PSR_SYS_MODE       @ Switch to System Mode
        msr     cpsr, r0
        ldr     sp, sp_usr              @ Set SP_usr
        ldr     r1, =INTR_VECTOR_BUF    @ Set Interrupt Address
        adr     r0, intr_main
        str     r0, [r1]
        ldr     r1, =AgbMain            @ Start & Switch to 16bit Code
        mov     lr, pc
        bx      r1
        b       start_vector            @ Reset

    .ALIGN
sp_usr: .word   WRAM_END - 0x100
sp_irq: .word   WRAM_END - 0x60


@--------------------------------------------------------------------
@-          Interrupt Branch Process (Draw from Table) 32Bit  27-62c-
@--------------------------------------------------------------------
    .EXTERN     IntrTableBuf
    .GLOBAL     intr_main
    .ALIGN
    .CODE 32
intr_main:
        mov     r12, #REG_BASE           @ r12: REG_BASE
        add     r3, r12, #OFFSET_REG_IE  @ r3:  REG_IE
        ldr     r2, [r3]
        and     r1, r2, r2, lsr #16      @ r1:  IE & IF
        mov     r2, #0                       @ Check IE/IF
	ands    r0, r1, #CASSETTE_INTR_FLAG  @ Game Pak Interrupt
loop:   bne     loop
        ands    r0, r1, #V_BLANK_INTR_FLAG   @ V Blank interrupt
        strneh  r0, [r12, #INTR_CHECK_BUF - WRAM_END] @ Set interrupt check
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #H_BLANK_INTR_FLAG   @ H Blank interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #V_COUNT_INTR_FLAG   @ V Balnk interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #TIMER0_INTR_FLAG    @ Timer 0 interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #TIMER1_INTR_FLAG    @ Timer 1 interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #TIMER2_INTR_FLAG    @ Timer 2 interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #TIMER3_INTR_FLAG    @ Timer 3 interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #SIO_INTR_FLAG       @ Serial communication interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #DMA0_INTR_FLAG      @ DMA0 interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #DMA1_INTR_FLAG      @ DMA1 interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #DMA2_INTR_FLAG      @ DMA2 interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #DMA3_INTR_FLAG      @ DMA3 interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #KEY_INTR_FLAG       @ Key interrupt
jump_intr:
        strh    r0, [r3, #2]            @ Clear IF           11c
        ldr     r1, =IntrTableBuf       @ Jump to user IRQ process
        add     r1, r1, r2
        ldr     r0, [r1]
        bx      r0


@   .ORG    0x200


    .END

